package de.mizi.ui.statusbox;

import java.awt.Graphics;
import java.util.HashMap;

import javax.swing.JPanel;

import de.mizi.controller.GameEvent;
import de.mizi.controller.GameListener;
import de.mizi.utility.FontData;

/**
 * A status box that displays different StatusBoxContent objects.
 * @author mizi
 *
 */
public class StatusBox extends JPanel implements GameListener {
	private FontData fontData;
	private HashMap<String, StatusBoxContent> content;
	
	private static final long serialVersionUID = 1L;

	/** 
	 * Constructs a new StatusBox object with the given FontData object.
	 * @param fontData the FontData object of this StatusBox object.
	 */
	public StatusBox(FontData fontData) {
		this.fontData = fontData;
		this.content = new HashMap<String, StatusBoxContent>();
	}
	
	/**
	 * Add a new StatusBoxContent object that shall be displayed by
	 * this StatusBox object.
	 * @param name the name of the content object used as an identifier
	 * @param c the new StatuxBoxContent object
	 */
	public void addContent(String name, StatusBoxContent c) {
		content.put(name, c);
		repaint();
	}
	
	/**
	 * Remove a StatuxBoxContent object from this StatusBox object.
	 * @param name the name of the content object used as an identifier
	 * @return the removed content or null if nothing was removed; null will also be
	 * returned if the content was explicitly null
	 */
	public StatusBoxContent removeContent(String name) {
		StatusBoxContent c = content.remove(name);
		repaint();
		return c;
	}
	
	/**
	 * Remove all StatusBoxContent objects from this StatusBox object.
	 */
	public void clearContent() {
		content.clear();
		repaint();
	}
	
	/**
	 * Returns true if this StatusBox object has a StatusBoxContent object
	 * with the given name.
	 * @param name the name of the content object used as an identifier
	 * @return true if this StatusBox objects has a StatusBoxContent object with
	 * the given name, false otherwise
	 */
	public boolean containsContent(String name) {
		return content.containsKey(name);
	}
	
	/**
	 * Sets the label of a StatusBoxContent object with the given name.
	 * @param name the name of the content object used as an identifier
	 * @param label the new label
	 * @return true if the label was changed, false otherwise (for example if a
	 * StatusBoxContent object with the given name was not found)
	 */
	public boolean setContentLabel(String name, String label) {
		boolean labelChanged = false;
		
		if(containsContent(name)) {
			StatusBoxContent c = content.get(name);
			if(c instanceof LabelOnlyContent) {
				((LabelOnlyContent)c).setLabel(label);
				labelChanged = true;
				repaint();
			}
		}
		
		return labelChanged;
	}
	
	/**
	 * Sets the first value of a StatusBoxContent object with the given name.
	 * @param name the name of the content object used as an identifier
	 * @param value the new value
	 * @return true if the value was changed, false otherwise (for example if a
	 * StatusBoxContent object with the given name was not found)
	 */
	public boolean setContentFirstValue(String name, int value) {
		boolean valueChanged = false;
		
		if(containsContent(name)) {
			StatusBoxContent c = content.get(name);
			if(c instanceof SingleValueContent) {
				((SingleValueContent)c).setValue(value);
				valueChanged = true;
				repaint();
			}
		}
		
		return valueChanged;
	}
	
	/**
	 * Sets the second value of a StatusBoxContent object with the given name.
	 * @param name the name of the content object used as an identifier
	 * @param value the new value
	 * @return true if the value was changed, false otherwise (for example if a
	 * StatusBoxContent object with the given name was not found)	 */
	public boolean setContentSecondValue(String name, int value) {
		boolean valueChanged = false;
		
		if(containsContent(name)) {
			StatusBoxContent c = content.get(name);
			if(c instanceof TwoValuesContent) {
				((TwoValuesContent)c).setValue2(value);
				valueChanged = true;
				repaint();
			}
		}
		
		return valueChanged;
	}
	
	@Override
	public void update(GameEvent event) {
		
	}
	
	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.setColor(fontData.fontColor);
		g.setFont(fontData.font);
		// Status
		for(String key: content.keySet()) {
			content.get(key).render(g, fontData.yOffset);
		}
	}
}
